home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part1 / 9489 < prev    next >
Encoding:
Internet Message Format  |  1996-08-05  |  8.2 KB

  1. Path: internet.roadrunner.com!richrcar
  2. From: richrcar@internet.roadrunner.com (James Giles)
  3. Newsgroups: comp.lang.misc,comp.lang.c,comp.lang.pl1
  4. Subject: Re: GOTO controversy
  5. Followup-To: comp.lang.misc,comp.lang.c,comp.lang.pl1
  6. Date: 11 Mar 1996 06:01:12 GMT
  7. Organization: The Santa Fe Institute
  8. Message-ID: <4i0fj8$sd3@tierra.santafe.edu>
  9. References: <rcshlds.1.000A6705@mailserv.mta.ca> <4grt4e$8fg@goanna.cs.rmit.EDU.AU> <4hl8mt$4po@newshost.cyberramp.net> <4hlg11$dd7@news1.mnsinc.com> <4hpits$1p1v@b.stat.purdue.edu>
  10. NNTP-Posting-Host: internet.roadrunner.com
  11. X-Newsreader: TIN [version 1.2 PL2]
  12.  
  13. In 1968, Edsger Dijkstra wrote a letter to the _Communications_
  14. _of_the_ACM_ titled "Go To Statement Considered Harmful".  This
  15. paper has since been widely reprinted.  In 1974, Donald Knuth
  16. wrote a paper for _Computing_Surveys_ titled "Structured
  17. Programming with GOTO Statements".  This paper has also been
  18. widely reprinted.  These were not the first nor the only papers
  19. written on this subject, but to my mind, they should have been
  20. the last needed.  Anyone who argues this issue should first
  21. be required to prove he (or she) has read both these papers.
  22. Anyone who hasn't read these papers should be ignored out
  23. of hand.
  24.  
  25. That being said, I'll go ahead and add my $0.02 to the mix.
  26.  
  27. I actually use GOTOs all the time.  Except for the "hello world" 
  28. program, my programs tend to have thousands of GOTO's.  For example,
  29. an IF without a ELSE clause has one conditional GOTO, with an ELSE
  30. there's both a conditional and an unconditional branch.  A WHILE 
  31. loop has both conditional and unconditional branches too.
  32.  
  33. Now this is both trivially obvious and rather silly.  But it still
  34. raises the question of why CASE, IF(ELSE), WHILE(FOR, etc.), and
  35. procedure calls are the only branches anointed as "structured". 
  36. It wasn't always so.  Though these were the constructs mentioned in 
  37. Dijkstra's letter on the subject, there was no suggestion that these 
  38. were the *ONLY* appropriate constructs.
  39.  
  40. It is instructive to read Dijkstra's "Notes on Structured Programming"
  41. in the book "Structured Programming" (Dijkstra, Dahl, Hoare, 1972).
  42. Appropriate control constructs (according to Dijkstra) are those which 
  43. are simple enough and well understood enough to reason about clearly 
  44. and which help to break down the code into smaller independently 
  45. understandable chunks.  So, even from a Dijkstra-conforming perspective,
  46. if a particular form of branch is easy to reason about and simplifies
  47. (or, at least doesn't complicate) the code, there is no reason not to
  48. use it.  That's how EXIT and CYCLE ('break' and 'continue' for you C 
  49. programmers) got accepted as (reasonably) "structured".  
  50.  
  51. I have papers from the 60's and 70's recommending the following 
  52. instead of GOTO's (I use a pseudo language deliberately unlike 
  53. any particular language for examples - this avoids the inevitable 
  54. irrelevant wars):
  55.  
  56.       while (cond1)            next: while(cond1)
  57.          ...some stuff...               ...some stuff...
  58.          if (not cond2)                 goto next if (cond2)
  59.             ...more stuff...            ...more stuff...
  60.          end if                      end while   
  61.       end while
  62.  
  63. Now the CYCLE statement would replace the GOTO these days, but is the 
  64. left version really easier to reason about?  I don't think so.  Is it
  65. better modularization?  I don't think so.  And it's slower unless the
  66. compiler is reasonably clever (to recognize an implicit branch to the
  67. end of the loop is the same as one back to the beginning).  Some real 
  68. purists may still prefer the left version - matter of taste in my opinion.
  69.  
  70. The corresponding example for the EXIT construct is much worse:
  71.  
  72.       done = false
  73.       while (cond1 and not done)     while(cond1)
  74.          ...some stuff...               ...some stuff...
  75.          done=cond2                     goto out if (cond2)
  76.          if (not done)                  ...more stuff...
  77.             ...more stuff...         end while
  78.          endif                   out: ...
  79.       end while
  80.  
  81. The left version was actually *recommended* by the "structured
  82. programming" zealots a while back (and perhaps by some of the real
  83. die-hard cases even now).  The EXIT statement encapsulates this
  84. kind of GOTO, but even without it I find the left version much less 
  85. appealing than the right - the left version is *less* understandable,
  86. it's not at all more modular, and it's obviously slower (even a very
  87. aggressively smart compiler probably won't do as well - and such a 
  88. compiler takes longer to run itself!).  Depending on the nature of
  89. the conditions and/or the computation being performed there may be
  90. a way of writing a structured code which isn't as bad as the left
  91. version - but in the general case I think this is a good as purists
  92. could manage.
  93.  
  94. I often think that auxiliary condition flags are much worse than 
  95. GOTOs in that instead of merely bypassing the intervening code, they
  96. skim along underneath occasionally intruding in the form of yet
  97. another redundant test of the flag.  It is often claimed that one
  98. of the problems with labeled statements is that you can't tell
  99. how many branches target it or where those are.  Well, tests of
  100. auxiliary flags have the same problem - you can't tell where
  101. it was set or how many different places might have manipulated
  102. it.  Branches do, however, have the property that a GOTO always
  103. lands at a unique local label whereas auxiliary flags might be
  104. referenced time and again throughout the code.  In general, the
  105. effect of such flags on the program's control flow can be more 
  106. complex than the effect of GOTOs.
  107.  
  108. Well so far all the "acceptable" branches have been amenable to 
  109. concealment under some name other than GOTO (even the original set
  110. like WHILE and IF).  Is that it?  Is merely changing the name 
  111. sufficient to make GOTO acceptable?  No, but it helps.  It helps
  112. because when you see just a GOTO in the middle of a code you must
  113. look up the associated label and discover for yourself the properties
  114. of the thing.  They may or may not be conducive to easier understanding
  115. or better modularization.  However when you see one of these named
  116. aliases for a particular type of GOTO, you have instantly a good idea
  117. what its properties are.  The purpose of the new name is not to conceal
  118. that branches are present, but to more explicitly pin down the properties 
  119. of those branches.
  120.  
  121. What about the other way around?  Are the only acceptable branches 
  122. those for which restrictive aliases are already common?  That would 
  123. imply that the control constructs we already have were a complete 
  124. set.  Well they are in a Turing-equivalency sense, but not necessarily 
  125. in the sense of being more easily understood, more modular, or both 
  126. (not to mention more efficient).  I'm not arrogant enough to claim 
  127. that I understand all useful types of control structures and that 
  128. GOTO should be left out of all languages so that people can't try 
  129. to invent new ones anymore.  Indeed, some of the uses of GOTO which 
  130. I personally find easy to understand and which I personally believe 
  131. tend to shorten and clarify the code are irritatingly illegal in 
  132. many of the programming languages I use (fortunately the need
  133. for them is rare).  Actually, if I had Zahn's situation indicators
  134. (as described in Knuth's paper referenced above) I would probably
  135. never need GOTOs again - but I don't have them.
  136.  
  137. Well, there's a lot more to talk about GOTOs (like exception handling!),
  138. but this is enough for one article.  The bottom line is that automatic
  139. rejection of GOTOs for religious reasons loses sight of the real issues
  140. which led to the controversy and often can lead to unfair disregard for
  141. techniques which are perfectly sound.  New kinds of GOTOs slowly reach
  142. into the "structured" pantheon, but only very slowly (and perhaps correctly
  143. so).  Complete elimination of GOTOs from available languages would stop
  144. this useful evolution entirely.  In any case, people should not be so quick
  145. to condemn *all* GOTOs out of hand.  As Dijkstra himself pointed out:
  146.  
  147.       Please don't fall into the trap of believing that I am terribly
  148.       dogmatical about it.  I have a feeling that others are making a 
  149.       religion out of it, as if the conceptual problems of programming
  150.       could be solved by a single trick, by a simple form of coding
  151.       discipline!
  152.                                       - E.W. Dijkstra
  153.